<template>
  <div style="padding: 0 10px">
    <n-tabs type="line" animated>
      <n-tab-pane name="oasis" tab="项目管理">
        <div style="padding: 10px; display: flex">
          <div class="left-content">
            <div style="display: flex">
              <!-- 选择文件夹 -->
              <button @click="openFolders">选择文件夹</button>
              <input
                type="text"
                v-model="foldersPath"
                placeholder="输入路径解析路径下所有文件夹"
                class="command-input"
              />

              <button @click="parsingPath">解析路径</button>
              <n-select
                v-model:value="packageManager"
                :options="getAddOptions()"
                placeholder="请选择包管理器"
                style="width: 150px; margin-right: 10px"
              />
              <button @click="addPackageManager">安装包管理器</button>
            </div>

            <!-- 显示已选择的文件夹路径及操作按钮 -->
            <div v-if="mappingData.length">
              <p>已选择的文件夹路径：</p>
              <!-- 按照路径分组处理 -->
              <div
                v-for="(data, index1) in mappingData"
                :key="index1"
                style="margin-bottom: 10px; padding-right: 10px"
              >
                <div
                  style="
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                  "
                >
                  <div style="display: flex; align-items: center">
                    <div style="margin-right: 10px">{{ data.key }}</div>
                    <n-switch v-model:value="data.show" @change="changeData">
                      <template #checked> 展开 </template>
                      <template #unchecked> 折叠 </template>
                    </n-switch>
                  </div>
                  <div style="display: flex; align-items: center">
                    <n-select
                      v-model:value="data.model"
                      :options="modelOptions"
                      placeholder="请选择修改内容"
                      style="width: 150px; margin-right: 10px"
                    />
                    <div v-if="data.model == '1'">
                      <input
                        type="text"
                        v-model="data.groupData"
                        placeholder="设置分组号"
                        class="command-input"
                        style="width: 150px; margin-right: 10px"
                      />
                    </div>
                    <div v-else-if="data.model == '2'">
                      <n-select
                        v-model:value="data.packageManager"
                        :options="options"
                        placeholder="请选择包管理器"
                        style="width: 150px; margin-right: 10px"
                      />
                    </div>
                    <div v-else>
                      <input
                        type="text"
                        v-model="data.startCommand"
                        placeholder="设置启动命令"
                        class="command-input"
                        style="width: 150px; margin-right: 10px"
                      />
                    </div>

                    <button @click="setMapping(data)">批量修改</button>
                    <button
                      @click="deleteMapping(index1)"
                      style="background-color: rgb(227 37 37)"
                    >
                      删除项目
                    </button>
                  </div>
                </div>

                <n-collapse-transition :show="data.show">
                  <ul>
                    <li v-for="(item, index2) in data.children" :key="index2">
                      <!-- 文件夹路径 -->
                      <div
                        style="
                          display: flex;
                          align-items: center;
                          margin-bottom: 20px;
                        "
                      >
                        <div style="margin-right: 20px">{{ item.name }}</div>
                        <button
                          @click="deleteFolderData(index1, index2)"
                          style="background-color: rgb(227 37 37)"
                        >
                          删除
                        </button>
                        <input
                          type="text"
                          v-model="item.groupData"
                          placeholder="设置分组号"
                          class="command-input"
                          @input="changeData"
                        />
                      </div>

                      <div style="display: flex; align-items: center">
                        <!-- 包管理器选择 -->
                        <div style="margin-right: 10px">选择包管理器:</div>
                        <n-space
                          vertical
                          style="width: 140px; margin-right: 10px"
                        >
                          <n-select
                            v-model:value="item.packageManager"
                            :options="options"
                            placeholder="请选择包管理器"
                          />
                        </n-space>
                        <!-- 操作按钮 -->
                        <button @click="installDependencies(item.path, item)">
                          安装依赖
                        </button>
                        <!-- 输入启动命令 -->
                        <input
                          type="text"
                          v-model="item.startCommand"
                          placeholder="请输入启动命令 (如: dev, start)"
                          class="command-input"
                          @input="changeData"
                        />

                        <button
                          @click="startProject(item.path, item.startCommand)"
                          :disabled="!item.startCommand"
                        >
                          启动项目
                        </button>

                        <button @click="invokeCMD(item.path)">唤起CMD</button>
                        <button @click="delModules(item.path)">
                          删除node_modules
                        </button>
                        <!-- 输入编译命令 -->
                        <!-- <input
                type="text"
                v-model="data.buildCommand"
                placeholder="请输入编译命令 (如: build)"
                class="command-input"
                @input="saveData"
              />
              <button
                @click="buildProject(data.path, data.buildCommand)"
                :disabled="!data.buildCommand"
              >
                编译项目
              </button> -->
                      </div>
                    </li>
                  </ul>
                </n-collapse-transition>
              </div>
            </div>

            <!-- 输出信息显示 -->
            <div v-if="outputLogs.length" class="output-container">
              <p>输出信息:</p>
              <pre>{{ outputLogs.join("\n") }}</pre>
            </div>
            <button
              @click="crash"
              style="background-color: rgb(227 37 37); margin-top: 10px"
              v-if="outputLogs.length"
            >
              清空输出信息
            </button>
          </div>
          <div class="right-content">
            <div>
              <input
                type="text"
                v-model="groupData"
                placeholder="请输入组名"
                class="command-input"
              />

              <button @click="saveGroupData">新增连锁启动组</button>
            </div>

            <div>tip:输入组号，给项目设置组号，就可以一键全启动</div>
            <div style="margin-top: 10px">分组信息：</div>
            <div
              v-for="(item, index) in groupDataList"
              :key="index"
              style="margin-bottom: 10px"
            >
              <div
                style="display: flex; align-items: center; margin-bottom: 10px"
              >
                <div style="margin-right: 10px">{{ item }}</div>
                <div>
                  <button
                    @click="deleteGroupData(index)"
                    style="background-color: rgb(227 37 37)"
                  >
                    删除分组
                  </button>
                  <button @click="oneClickStart(item)">一键启动</button>
                </div>
              </div>
              <div v-for="p in getGroupDataList(item)">
                {{ p }}
              </div>
            </div>
          </div>
        </div>
      </n-tab-pane>
      <n-tab-pane name="the beatles" tab="其他功能">
        <div>
          <!-- <div>nvm (当弹出nvm报错的时候，请用`兼容获取已安装Node版本`):</div> -->
          <div class="title-red">nvm:</div>
          <div style="display: flex; align-items: center">
            <button @click="nvmCmd(1)">跳转nvm下载地址</button>
            <button @click="nvmCmd(2)">查看可用Node版本</button>
            <button @click="nvmCmd(3)">列出已安装Node版本</button>

            <input
              type="text"
              v-model="nodeInputVersion"
              placeholder="请输入可用版本"
              class="command-input"
            />

            <button @click="nvmCmd(4)">安装对应Node</button>
            <n-select
              v-model:value="nodeSelectVersion"
              :options="nodeList"
              placeholder="请选择可用版本"
              style="width: 110px; margin-right: 10px"
            />
            <button @click="nvmCmd(5)">切换到所选Node</button>
            <!-- <button @click="nvmCmd(6)">兼容获取已安装Node版本</button> -->
          </div>
        </div>
        <div style="margin: 10px 0">
          <div class="title-red">一键唤起多个软件:</div>
          <div>
            <input
              type="text"
              v-model="wakeUpGroupNumber"
              placeholder="请输入唤醒组号"
              class="command-input"
            />

            <button @click="wakeUpGroup">新增唤醒组</button>
          </div>
          <div v-if="wakeUpGroupList.length">
            <div style="margin-top: 10px">唤醒组信息：</div>
            <div
              v-for="(item, index) in wakeUpGroupList"
              :key="index"
              style="margin-bottom: 10px"
            >
              <div
                style="display: flex; align-items: center; margin-bottom: 10px"
              >
                <div style="margin-right: 10px">组号：{{ item.key }}</div>
                <div>
                  <button @click="wakeUpGroupPath(item)">选择唤醒路径</button>
                  <button @click="wake(item)" :disabled="!item.children.length">
                    一键唤醒
                  </button>
                  <button
                    style="background-color: rgb(227 37 37)"
                    @click="
                      item.children = [];
                      saveWakeUpGroup();
                    "
                  >
                    清空唤醒路径
                  </button>
                  <button
                    @click="deleteWakeUpGroup(index)"
                    style="background-color: rgb(227 37 37)"
                  >
                    删除唤醒组
                  </button>
                </div>
              </div>
              <div>
                <span v-for="p in item.children">
                  {{ p }} &nbsp;&nbsp;&nbsp;&nbsp;
                </span>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div class="title-red">当前目录下，批量重命名：</div>
          <div>
            <input
              type="text"
              v-model="batchRename"
              placeholder="输入需要批量重命名的文件夹路径"
              class="command-input"
              style="width: 300px"
            />
            <input
              type="text"
              v-model="batchRenameRule"
              placeholder="输入需要批量重命名规则"
              class="command-input"
              style="width: 200px"
            />
            <button @click="batchRenameFileIncrement">
              批量重命名（自增）
            </button>
            <button @click="batchRenameFileReplace">批量重命名（替换）</button>
            <n-switch v-model:value="replaceExt">
              <template #checked> 替换后缀 </template>
              <template #unchecked> 不替换后缀 </template>
            </n-switch>
          </div>
          <div>
            tip:
            批量重命名规则，自增：输入例如，测试${1}.png，那么文件夹下的会按顺序命名成
            测试1.png，测试2.png，等，${
            }符号内的会被解析成自增数字。替换：输入例如 ${png}${jpg},文件夹下的
            1.png,2.png 会被替换成 1.jpg，2.jpg等
          </div>
        </div>
      </n-tab-pane>
    </n-tabs>
  </div>
  <n-modal v-model:show="showModal" preset="dialog" :title="modaltitle">
    <span v-html="modaltitleContent"></span
  ></n-modal>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, watch } from "vue";
import {
  NSpace,
  NSelect,
  NTooltip,
  NTabs,
  NTabPane,
  NSwitch,
  NCollapseTransition,
  createDiscreteApi,
  NModal,
} from "naive-ui";
// 定义数据结构
interface FolderData {
  key: string;
  name: string;
  path: string;
  startCommand: string;
  buildCommand: string;
  packageManager: string;
  groupData: string | number;
}
// 定义 mappingData 的类型
interface MappingData {
  key: string;
  show: boolean;
  model: string;
  groupData?: string | number;
  packageManager?: string;
  startCommand?: string;
  children: FolderData[];
}
interface WakeUpGroupList {
  key: string;
  wakeUpGroupPath: string;
  children: String[];
}
// 初始化文件夹数据
// 项目信息存储
const mappingData = ref<MappingData[]>([]);
// 输出信息
const outputLogs = ref<string[]>([]);
const packageManager = ref<string>("pnpm");
const foldersPath = ref<string>("");
const showModal = ref(false);
const modaltitleContent = ref<any>("");
const modaltitle = ref("当前安装的node版本");
const { message } = createDiscreteApi(["message"]);
const nodeInputVersion = ref<string>("");
const nodeSelectVersion = ref<string>("");
const nodeList = ref<any>([]);
const wakeUpGroupNumber = ref<string>("");
const wakeUpGroupList = ref<WakeUpGroupList[]>([]);
// 包管理器选项
const options = [
  { label: "npm", value: "npm" },
  { label: "pnpm", value: "pnpm" },
  { label: "yarn", value: "yarn" },
  { label: "cnpm", value: "cnpm" },
];
const modelOptions = [
  { label: "修改分组号", value: "1" },
  { label: "修改包管理器", value: "2" },
  { label: "修改启动命令", value: "3" },
];
//存储分组信息
const groupData = ref<string>("");
const groupDataList = ref<string[]>([]);
const batchRename = ref<string>(""); //批量文件夹修改路径
const batchRenameRule = ref<string>(""); //批量文件夹修改规则
const replaceExt = ref<boolean>(true);
const saveMappingData = (paths: string[]) => {
  if (paths && paths.length > 0) {
    const newMappingData = [...mappingData.value]; // 创建 mappingData 的副本
    paths.forEach((path) => {
      let key2 = path.substring(0, path.lastIndexOf("\\"));
      let newFolderData = {
        key: key2, // 提取路径的前缀作为 key
        name: path.substring(path.lastIndexOf("\\") + 1),
        path,
        startCommand: "",
        buildCommand: "",
        packageManager: "npm",
        groupData: "",
      };

      // 检查 key 是否已存在
      let existingKey = newMappingData.find((item) => item.key === key2);

      if (existingKey) {
        // 如果 key 存在，则检查是否已存在相同的 path
        if (!existingKey.children.some((item) => item.path === path)) {
          existingKey.children.push(newFolderData);
        }
      } else {
        // 如果 key 不存在，则添加新的结构
        newMappingData.push({
          key: key2,
          model: "1",
          show: false,
          children: [newFolderData],
        });
      }
    });

    mappingData.value = newMappingData; // 一次性修改 mappingData.value
    saveData(); // 保存数据
  }
};
// 打开文件夹
const openFolders = async () => {
  const paths = await window.ipcFn.selectFolders();
  saveMappingData(paths);
};
const clearData = () => {
  localStorage.clear();
  mappingData.value = [];
};
// 保存数据到本地存储
const saveData = () => {
  localStorage.setItem("mappingData", JSON.stringify(mappingData.value));
};
const changeData = () => {
  saveData();
};
// 加载数据
const loadData = () => {
  const savedData = localStorage.getItem("mappingData");
  if (savedData) {
    mappingData.value = JSON.parse(savedData);
  }
  const savedGroupData = localStorage.getItem("groupDataList");
  if (savedGroupData) {
    groupDataList.value = JSON.parse(savedGroupData);
  }
  const wakeUpGroupData = localStorage.getItem("wakeUpGroupList");
  if (wakeUpGroupData) {
    wakeUpGroupList.value = JSON.parse(wakeUpGroupData);
  }
};

// 安装依赖
const installDependencies = async (path: string, row: FolderData) => {
  let packageManager = row.packageManager;
  if (packageManager !== "npm") {
    const confirmMsg = `您选择了 ${packageManager} 作为包管理器，确保您已经安装了它。`;
    if (!confirm(confirmMsg)) {
      row.packageManager = "npm"; // 如果用户取消，恢复为npm
      packageManager = "npm";
    }
  }
  let command = `${packageManager} install`;
  // const result = await window.ipcFn.installDependencies(path, packageManager);
  const result = await window.ipcFn.executeCommand(path, command);
  outputLogs.value.push(result); // 处理结果
};

// 启动项目
const startProject = async (path: string, command: string) => {
  try {
    const startCommand = `npm run ${command}`;
    const result = await window.ipcFn.executeCommand(path, startCommand);
    outputLogs.value.push(result); // 处理结果
  } catch (error) {
    // 处理错误情况
    outputLogs.value.push(`运行错误: ${error}`);
  }
};

// 编译项目
const buildProject = async (path: string, command: string) => {
  const buildCommand = `npm run ${command}`;
  const result = await window.ipcFn.executeCommand(path, buildCommand);
  outputLogs.value.push(result); // 处理结果
};
// 删除项目数据
const deleteFolderData = (index1: number, index2: number) => {
  mappingData.value[index1].children.splice(index2, 1);
  saveData();
};
// 删除分组数据
const deleteGroupData = (index: number) => {
  groupDataList.value.splice(index, 1);
  localStorage.setItem("groupDataList", JSON.stringify(groupDataList.value));
};
const deleteMapping = (index1: number) => {
  mappingData.value.splice(index1, 1);
  saveData();
};
// 清空输出信息
const crash = () => {
  outputLogs.value = [];
};
// 保存分组数据
const saveGroupData = () => {
  if (groupData.value) {
    if (groupDataList.value.includes(groupData.value)) {
      message.warning("分组已存在");
      return;
    } else {
      groupDataList.value.push(groupData.value);
      groupData.value = "";
      localStorage.setItem(
        "groupDataList",
        JSON.stringify(groupDataList.value)
      );
    }
  } else {
    message.warning("请输入分组名");
    return;
  }
};
const getTeamArr = (groupData: string) => {
  let arr = [];
  mappingData.value.forEach((item1) => {
    item1.children.forEach((item2) => {
      if (item2.groupData === groupData) {
        arr.push(item2);
      }
    });
  });
  return arr;
};
// 获取分组数据
const getGroupDataList = (groupData: string) => {
  let arr = getTeamArr(groupData);
  return arr.map((item) => item.path);
};
// 一键启动
const oneClickStart = (groupData: string) => {
  let arr = getTeamArr(groupData);
  arr.forEach((item) => {
    if (item.startCommand) {
      startProject(item.path, item.startCommand);
    } else {
      //提示
      message.warning(`${item.path} 启动失败，请先设置启动命令`);
    }
  });
};
//唤醒cmd
const invokeCMD = async (path: string) => {
  const result = await window.ipcFn.executeCommand(path, "");
};
const setMapping = (data: any) => {
  if (data.model == "1") {
    data.children.forEach((item: FolderData) => {
      item.groupData = data.groupData;
    });
    saveData();
  } else if (data.model == "2") {
    if (data.packageManager) {
      data.children.forEach((item: FolderData) => {
        item.packageManager = data.packageManager;
      });
      saveData();
    } else {
      message.warning("请选择包管理器");
    }
  } else {
    data.children.forEach((item: FolderData) => {
      item.startCommand = data.startCommand;
    });
    saveData();
  }
};
const delModules = async (path: string) => {
  try {
    const command = `rmdir /S /Q node_modules`;
    const result = await window.ipcFn.executeCommand(path, command);
    outputLogs.value.push(result); // 处理结果
  } catch (error) {
    // 处理错误情况
    outputLogs.value.push(`运行错误: ${error}`);
  }
};
const getAddOptions = () => {
  let arr = [];
  options.forEach((item) => {
    if (item.label != "npm") {
      arr.push(JSON.parse(JSON.stringify(item)));
    }
  });
  return arr;
};
const addPackageManager = async () => {
  try {
    const command = `npm install ${packageManager.value} -g`;
    const result = await window.ipcFn.executeCommand("C:\\", command);
    // outputLogs.value.push(result); // 处理结果
  } catch (error) {
    // 处理错误情况
    outputLogs.value.push(`运行错误: ${error}`);
  }
};
const parsingPath = async () => {
  if (foldersPath.value) {
    const result = await window.ipcFn.readAllFolders(foldersPath.value);
    saveMappingData(result);
    message.success("成功解析");
  } else {
    message.warning("请输入路径");
  }
};
function parseVersionInfo(inputString) {
  // 将输入字符串按行分割
  const lines = inputString.trim().split("\n");

  // 初始化结果数组
  const result = [];

  // 遍历每一行
  lines.forEach((line) => {
    // 去掉左右空格
    line = line.trim();

    // 如果这一行包含 '*'
    if (line.startsWith("*")) {
      // 去掉前面的 '* ' 并获取版本号
      const currentVersion = line.substring(2).split(" ")[0];

      // 将当前版本添加到结果数组，并设置 disabled 为 true
      result.push({
        label: currentVersion,
        value: currentVersion,
        disabled: true,
      });
    } else {
      // 获取其他版本号
      const version = line.split(" ")[0];

      // 将其他版本添加到结果数组
      result.push({
        label: version,
        value: version,
      });
    }
  });

  return result;
}
async function getNodeVersion() {
  let list = await window.ipcFn.getNodeList();
  nodeList.value = parseVersionInfo(list);
  modaltitleContent.value = `<pre>${list}</pre>`;
}
const nvmCmd = async (type: number) => {
  let result = "";
  let command = "";
  switch (type) {
    case 1:
      window.ipcFn.openUrl(
        "https://github.com/coreybutler/nvm-windows/releases"
      );
      message.success("已跳转");
      break;
    case 2:
      command = "nvm list available";
      message.success("提示：nvm服务器在外网，请等待相应，或者配置代理");
      break;
    case 3:
      getNodeVersion();
      showModal.value = true;
      break;
    case 4:
      if (nodeInputVersion.value) {
        command = `nvm install ${nodeInputVersion.value}`;
      } else {
        message.warning("请输入版本号");
        return;
      }
      break;
    case 5:
      if (nodeSelectVersion.value) {
        command = `nvm use ${nodeSelectVersion.value}`;
      } else {
        message.warning("请选择版本号");
        return;
      }
      // const nodeList = ref<any>([]);
      break;
    // case 6:
    //   let list = await window.ipcFn.getNodeList(true);
    //   console.log(list, 666);
    //   nodeList.value = parseVersionInfo(list);
    //   modaltitleContent.value = `<pre>${list}</pre>`;
    //   break;
  }
  if (command) {
    result = await window.ipcFn.executeCommand("C:\\", command);
  }
};
const saveWakeUpGroup = () => {
  localStorage.setItem(
    "wakeUpGroupList",
    JSON.stringify(wakeUpGroupList.value)
  );
};
const wakeUpGroup = () => {
  if (wakeUpGroupNumber.value) {
    wakeUpGroupList.value.push({
      key: wakeUpGroupNumber.value,
      wakeUpGroupPath: "",
      children: [],
    });
    saveWakeUpGroup();
  } else {
    message.warning("请输入唤醒组号");
  }
};
const wakeUpGroupPath = async (item: WakeUpGroupList) => {
  const paths: any = await window.ipcFn.selectFiles();
  if (paths && paths.length > 0) {
    item.children = [...item.children, ...paths];
    saveWakeUpGroup();
  }
};
const wake = async (item: WakeUpGroupList) => {
  const childrenAsString = item.children.map((child) => child.toString());
  window.ipcFn.launchFiles(childrenAsString);
};
//删除唤醒组
const deleteWakeUpGroup = (index: number) => {
  wakeUpGroupList.value.splice(index, 1);
  saveWakeUpGroup();
};
// 批量修改文件夹下文件
// 自增
const batchRenameFileIncrement = async () => {
  if (!batchRename.value) {
    message.warning("请输入需要修改的文件夹路径");
    return;
  }
  if (!batchRenameRule.value) {
    message.warning("请输入自增规则");
    return;
  }

  try {
    let result = await window.ipcFn.batchRenameFileIncrement(
      batchRename.value,
      batchRenameRule.value,
      replaceExt.value
    );
    message.success(result);
  } catch (error) {
    // 如果发生异常，提示错误信息
    message.error(error);
  }
};

// 替换
const batchRenameFileReplace = async () => {
  if (!batchRename.value) {
    message.warning("请输入需要修改的文件夹路径");
    return;
  }
  if (!batchRenameRule.value) {
    message.warning("请输入替换规则");
    return;
  }

  try {
    let result = await window.ipcFn.batchRenameFileReplace(
      batchRename.value,
      batchRenameRule.value,
      replaceExt.value
    );

    message.success(result);
  } catch (error) {
    // 如果发生异常，提示错误信息
    message.error(`操作失败: ${error.message || "未知错误"}`);
  }
};

// 在组件加载时加载数据
onMounted(() => {
  loadData();
  getNodeVersion();
});
</script>

<style scoped lang="scss">
button {
  padding: 8px 16px;
  background-color: #4caf50;
  color: white;
  border: none;
  cursor: pointer;
  margin-right: 8px;
}

button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

button:hover:enabled {
  background-color: #45a049;
}

.command-input {
  padding: 8px;
  margin-right: 8px;
  width: 200px;
}

.output-container {
  margin-top: 20px;
  background-color: #f4f4f4;
  padding: 10px;
  border: 1px solid #ddd;
  max-height: 300px;
  overflow-y: scroll;
}

pre {
  white-space: pre-wrap;
  word-wrap: break-word;
}

ul {
  list-style-type: none;
  padding-left: 0;
}

li {
  margin-bottom: 16px;
}

div {
  font-family: Arial, sans-serif;
}
.left-content {
  width: calc(100vw - 400px);
  height: calc(100vh - 122px);
  overflow-y: auto;
}
.right-content {
  border-left: 1px solid #eeeeee;
  padding: 0 10px;
  width: 400px;
  height: calc(100vh - 122px);
  overflow-y: auto;
}
.title-red {
  color: red;
}
</style>
<style>
.n-message-container {
  transform: translateY(23px);
}
</style>
